/**
 * 前端战斗引擎
 * 负责处理战斗逻辑、动画和与后端的数据交互
 */

import { request } from '../api/request'

export class BattleEngine {
  constructor() {
    this.battleData = null
    this.battleState = {
      currentRound: 0,
      isFinished: false,
      winner: null,
      battleLog: [],
      totalDamageDealt: 0,
      totalDamageTaken: 0,
      skillsUsed: [],
      criticalHits: 0,
      battleStartTime: null,
      battleId: null
    }
    this.playerUnits = []
    this.enemyUnits = []
    this.turnQueue = []
    // 提高单位生命值倍率，便于观察整体战斗
    this.hpMultiplier = 3
    // 仅后端驱动模式
    this.mode = 'backend'
    this.events = []
    this.eventIndex = 0
    
    // 技能效果串行队列
    this.skillEffectQueue = []
    this.isProcessingSkillEffect = false

    // 动画回调函数
    this.onCurrentAction = null  // 当前行动回调

    // 统一动画配置与速度倍率（1 为基准，<1 加速，>1 减速）
    this.animationConfig = {
      speedMultiplier: 1,
      durations: {
        line: { // 连线时长（ms）（备用，不再单独使用）
          '攻击': 1000,
          '辅助': 1100,
          '控制': 1200,
          '默认': 1000
        },
        effect: { // 命中效果展示（ms）- 更短，数字与效果更同步
          '攻击': 500,
          '辅助': 650,
          '控制': 750,
          '默认': 500
        },
        interval: { // 子效果间隔（ms）- 缩短，提升节奏
          '攻击': 400,
          '辅助': 500,
          '控制': 600,
          '默认': 450
        },
        ui: { // 页面级 CSS 变量（ms）- 更快的数字出现与消退
          damageMs: 700,
          attackMs: 800,
          healMs: 1000,
          buffMs: 900,
          skillMs: 1500,
          // 划线到达与清线之间的微小延时（用于保证“线到即掉血”的观感）
          hitSyncDelayMs: 30
        }
      }
    }
  }

  // 新增：从后端数据初始化单位
  initializeUnitsFromBackend() {
    // 处理玩家队伍，确保按position排序并处理空位
    this.playerUnits = this.processTeamData(this.battleData.origin_player_team || [], true)
    // 处理敌方队伍，确保按position排序并处理空位  
    this.enemyUnits = this.processTeamData(this.battleData.origin_opponent_team || [], false)
  }

  // 新增：处理队伍数据，确保正确的位置排列和空位处理
  processTeamData(teamData, isPlayer) {
    const units = []
    
    // 创建6个位置的数组（1-6）
    for (let pos = 1; pos <= 6; pos++) {
      const unitAtPosition = teamData.find(unit => unit.position === pos && unit.id)
      
      if (unitAtPosition && unitAtPosition.id) {
        // 有单位在这个位置
        units.push({
          ...unitAtPosition,
          hp: unitAtPosition.health || unitAtPosition.hp || 100,
          maxHp: unitAtPosition.health || unitAtPosition.hp || 100,
          isPlayer: isPlayer,
          isAlive: true,
          statusEffects: unitAtPosition.statusEffects || [],
          // 确保position字段正确
          position: pos
        })
      } else {
        // 这个位置是空的，创建占位符
        units.push({
          id: null,
          name: '',
          isPlaceholder: true,
          position: pos,
          type: isPlayer ? 'player' : 'enemy',
          isPlayer: isPlayer,
          isAlive: false
        })
      }
    }
    
    // 过滤掉占位符，只返回实际的单位
    return units.filter(unit => !unit.isPlaceholder)
  }

  // 新增：从后端数据加载事件
  loadEventsFromBackend() {
    this.events = this.battleData.battle_log || []
    this.eventIndex = 0
  }
    
    /**
     * 初始化模拟数据（用于测试）
     */
    initializeMockData() { /* 已移除AI/本地模拟，保留空实现以避免外部调用报错 */ }

    /**
   * 初始化战斗数据
   * @param {string} battleType - 战斗类型 (pve, pvp)
   * @param {string} targetId - 目标ID
   */
  async initBattle(battleType, targetId) {
    try {
      const response = await request({
        url: '/combat/init',
        method: 'POST',
        data: {
          team_id: 1
        }
      })

      if (response.code === 1) {
        this.battleData = response.data
        this.battleState.battleId = response.data.battle_id
        this.battleState.battleStartTime = Date.now()
        // 仅使用后端驱动数据
        this.mode = 'backend'
        this.initializeUnitsFromBackend()
        this.loadEventsFromBackend()
        return true
      } else {
        console.error('战斗初始化失败:', response.msg)
        return false
      }
    } catch (error) {
      console.error('战斗初始化错误:', error)
      return false
    }
  }

  /**
   * 初始化战斗单位
   */
  initializeUnits() {
    // 检查战斗数据是否存在
    if (!this.battleData) {
      console.error('战斗数据未初始化')
      return
    }

    // 初始化玩家单位
    const playerFormation = this.battleData.player_formation || []
    this.playerUnits = playerFormation.map(unit => ({
      id: unit.id,
      name: unit.name,
      type: 'player',
      position: unit.position,
      hp: Math.floor(((this.battleData.player_attributes?.[unit.id]?.hp || 100)) * (this.hpMultiplier || 1)),
      maxHp: Math.floor(((this.battleData.player_attributes?.[unit.id]?.hp || 100)) * (this.hpMultiplier || 1)),
      baseDamage: this.battleData.player_attributes?.[unit.id]?.baseDamage || this.battleData.player_attributes?.[unit.id]?.attack || 20,
      defense: this.battleData.player_attributes?.[unit.id]?.defense || 10,
      speed: this.battleData.player_attributes?.[unit.id]?.speed || 15,
      critRate: this.battleData.player_attributes?.[unit.id]?.critRate || 5,
      hitRate: this.battleData.player_attributes?.[unit.id]?.hitRate || 95,
      dodgeRate: this.battleData.player_attributes?.[unit.id]?.dodgeRate || 5,
      damageIncrease: this.battleData.player_attributes?.[unit.id]?.damageIncrease || 0,
      damageReduction: this.battleData.player_attributes?.[unit.id]?.damageReduction || 0,
      skills: this.battleData.player_skills?.[unit.id] || [],
      statusEffects: [],
      isAlive: true
    }))

    // 初始化敌方单位
    const enemyFormation = this.battleData.enemy_formation || []
    this.enemyUnits = enemyFormation.map(unit => ({
      id: unit.id,
      name: unit.name,
      type: 'enemy',
      position: unit.position,
      hp: Math.floor(((this.battleData.enemy_attributes?.[unit.id]?.hp || 80)) * (this.hpMultiplier || 1)),
      maxHp: Math.floor(((this.battleData.enemy_attributes?.[unit.id]?.hp || 80)) * (this.hpMultiplier || 1)),
      baseDamage: this.battleData.enemy_attributes?.[unit.id]?.baseDamage || this.battleData.enemy_attributes?.[unit.id]?.attack || 18,
      defense: this.battleData.enemy_attributes?.[unit.id]?.defense || 8,
      speed: this.battleData.enemy_attributes?.[unit.id]?.speed || 12,
      critRate: this.battleData.enemy_attributes?.[unit.id]?.critRate || 5,
      hitRate: this.battleData.enemy_attributes?.[unit.id]?.hitRate || 90,
      dodgeRate: this.battleData.enemy_attributes?.[unit.id]?.dodgeRate || 5,
      damageIncrease: this.battleData.enemy_attributes?.[unit.id]?.damageIncrease || 0,
      damageReduction: this.battleData.enemy_attributes?.[unit.id]?.damageReduction || 0,
      skills: this.battleData.enemy_skills?.[unit.id] || [],
      statusEffects: [],
      isAlive: true
    }))

    console.log('战斗单位初始化完成:', {
      playerUnits: this.playerUnits.length,
      enemyUnits: this.enemyUnits.length
    })
  }

  calculateTurnOrder() { /* 后端驱动下不再使用 */ }

  /**
   * 执行一个回合 / 或事件步进（后端驱动）
   */
  async executeRound() { /* 后端驱动下不再使用 */ }

  /**
   * 播放下一个后端事件（严格按 battle_log）
   */
  async playNextEvent() {
    if (!this.events || this.eventIndex >= this.events.length) {
      // 无更多事件,依据后端标志结束
      if (this.battleData && this.battleData.is_finished) {
        this.battleState.isFinished = true
        this.battleState.winner = this.battleData.winner || null
      }
      return
    }

    const evt = this.events[this.eventIndex]
    this.eventIndex += 1

    // 事件类型分派：通过 actorId 特殊标识
    if (evt.actorId === 'round_start') {
      // 立即显示回合开始信息
      if (this.onCurrentAction && typeof this.onCurrentAction === 'function') {
        this.onCurrentAction(evt)
      }
      if (evt.description) {
        this.addLog(evt.description)
        if (this.onLog) this.onLog(evt.description)
      }
      this.battleState.currentRound = evt.round || (this.battleState.currentRound + 1)
      if (evt.updateAttr) this.applyUpdateAttr(evt.updateAttr)
      if (evt.curStatusEffect) this.applyCurStatusEffect(evt.curStatusEffect)
      return
    }
    if (evt.actorId === 'round_end') {
      // 立即显示回合结束信息
      if (this.onCurrentAction && typeof this.onCurrentAction === 'function') {
        this.onCurrentAction(evt)
      }
      if (evt.description) {
        this.addLog(evt.description)
        if (this.onLog) this.onLog(evt.description)
      }
      if (evt.updateAttr) this.applyUpdateAttr(evt.updateAttr)
      if (evt.curStatusEffect) this.applyCurStatusEffect(evt.curStatusEffect)
      return
    }
    if (evt.actorId === 'fight_end') {
      this.battleState.isFinished = true
      this.battleState.winner = this.battleData && this.battleData.winner ? this.battleData.winner : null
      return
    }

    // 普通攻击 - 重新整理执行顺序
    if (evt.normal_attack) {
      await this.executeNormalAttack(evt)
      return
    }

    // 技能效果（可能为数组多个子效果）- 改为串行队列执行
    if (evt.battleSkillEffect && Array.isArray(evt.battleSkillEffect)) {
      await this.executeSkillEffects(evt)
      return
    }
  }

  /**
   * 执行普通攻击 - 确保文字、动画、效果同步
   */
  async executeNormalAttack(evt) {
    const action = evt.normal_attack
    const attacker = this.findUnitByAnyKey(action.actorId || evt.actorId)

    // 阶段1：显示行动开始信息（文字）
    if (this.onCurrentAction && typeof this.onCurrentAction === 'function') {
      this.onCurrentAction(evt)
    }
    if (evt.description) {
      this.addLog(evt.description)
      if (this.onLog) this.onLog(evt.description)
    }

    // 事件级别buff弹窗
    if (evt.buffName && typeof evt.buffName === 'string' && evt.buffName.trim()) {
      if (this.onLog) this.onLog(`获得状态：${evt.buffName}`)
      if (this.onBuffPopup && attacker) this.onBuffPopup(attacker, evt.buffName)
    }

    // 阶段2：开始动画（连线）
    if (this.onSkillTargets && Array.isArray(action.targetList)) {
      const targetIds = action.targetList.map(t => t && t.targetId).filter(Boolean)
      this.onSkillTargets(action.actorId || evt.actorId, targetIds, action.actionType || evt.actionType || '攻击')
    }

    // 阶段3：等待动画完成
    const lineDuration = this.getLineAnimationDuration(action.actionType || evt.actionType || '攻击')
    await new Promise(resolve => setTimeout(resolve, lineDuration))

    // 阶段4：触发效果（掉血、状态变化）
    if (Array.isArray(action.targetList)) {
      for (let i = 0; i < action.targetList.length; i++) {
        const t = action.targetList[i]
        const target = this.findUnitByAnyKey(t.targetId)
        // 属性更新与视觉效果在命中瞬间同步触发
        this.applyTargetUpdateAttr(target, t.updateAttr)
        // 动画 + 文字播报同步触发
        if (t.damage && t.damage > 0) {
          this.triggerDamageAnimation(target, t.damage, !!t.isCrit, attacker)
        }
        if (t.heal && t.heal > 0) {
          this.triggerHealAnimation(target, t.heal)
        }
        // 状态变更（完整覆盖）
        if (t.updateStatusEffect) {
          this.applyTargetStatusEffect(target, t.updateStatusEffect)
        }
        // 新增状态（增量追加）
        if (t.addStatusEffect) {
          this.appendTargetStatusEffect(target, t.addStatusEffect)
          if (this.onBuffPopup && target) {
            const list = Array.isArray(t.addStatusEffect) ? t.addStatusEffect : [t.addStatusEffect]
            list.forEach(name => {
              if (typeof name === 'string' && name.trim()) this.onBuffPopup(target, name)
            })
          }
        }
        // 多目标尽量无等待，保证数字与效果同步
        if (i < action.targetList.length - 1) {
          await new Promise(resolve => setTimeout(resolve, 0))
        }
      }
    }
  }

  /**
   * 执行技能效果 - 确保文字、动画、效果同步
   */
  async executeSkillEffects(evt) {
    const caster = this.findUnitByAnyKey(evt.actorId)

    // 阶段1：显示行动开始信息（文字）
    if (this.onCurrentAction && typeof this.onCurrentAction === 'function') {
      this.onCurrentAction(evt)
    }
    if (evt.description) {
      this.addLog(evt.description)
      if (this.onLog) this.onLog(evt.description)
    }

    // 事件级别buff弹窗（同时将状态追加到施法者卡片）
    if (evt.buffName && typeof evt.buffName === 'string' && evt.buffName.trim()) {
      if (this.onLog) this.onLog(`获得状态：${evt.buffName}`)
      if (this.onBuffPopup && caster) this.onBuffPopup(caster, evt.buffName)
      if (caster) this.appendTargetStatusEffect(caster, evt.buffName)
    }

    // 阶段2：严格串行执行本次事件的多个技能效果，确保全部动画与效果完成后再返回
    const effects = Array.isArray(evt.battleSkillEffect) ? evt.battleSkillEffect : []
    for (let i = 0; i < effects.length; i++) {
      const eff = effects[i]
      // 组合参数并依次执行
      await this.processSingleSkillEffect({
        actorId: evt.actorId,
        caster,
        effect: eff,
        defaultActionType: evt.actionType
      })
      // 根据技能类型设置效果间隔（统一配置）
      const actionType = eff?.actionType || evt.actionType || '攻击'
      const interval = this.getIntervalForActionType(actionType)
      // 最后一个子效果不再额外等待
      if (i < effects.length - 1) {
        await new Promise(resolve => setTimeout(resolve, interval))
      }
    }
  }

  // 根据 updateAttr 映射批量更新单位属性
  // 新增：技能效果串行队列处理
  enqueueSkillEffects(actorId, skillEffects, defaultActionType) {
    const caster = this.findUnitByAnyKey(actorId)
    if (!caster || !Array.isArray(skillEffects)) return
    
    // 将每个技能效果作为独立项加入队列
    skillEffects.forEach(eff => {
      this.skillEffectQueue.push({
        actorId,
        caster,
        effect: eff,
        defaultActionType
      })
    })
    
    // 开始处理队列
    this.processSkillEffectQueue()
  }
  
  async processSkillEffectQueue() {
    if (this.isProcessingSkillEffect || this.skillEffectQueue.length === 0) return
    
    this.isProcessingSkillEffect = true
    
    // 同步顺序处理所有技能效果
    while (this.skillEffectQueue.length > 0) {
      const item = this.skillEffectQueue.shift()
      
      if (item) {
        // 等待当前技能效果完全执行完毕
        await this.processSingleSkillEffect(item)
        
        // 根据技能类型调整间隔时间（加快1倍）
        const actionType = item?.effect?.actionType || item?.defaultActionType || '攻击'
        let interval = 3750 // 默认间隔（原7500ms ÷ 2）

        switch (actionType) {
          case '攻击':
            interval = 3000 // 攻击类技能间隔稍短（原6000ms ÷ 2）
            break
          case '辅助':
            interval = 4500 // 辅助类技能间隔较长（原9000ms ÷ 2）
            break
          case '控制':
            interval = 5000 // 控制类技能间隔最长（原10000ms ÷ 2）
            break
          default:
            interval = 3750
        }
        
        // 如果还有下一个技能效果，等待间隔时间
        if (this.skillEffectQueue.length > 0) {
          await new Promise(resolve => setTimeout(resolve, interval))
        }
      }
    }
    
    this.isProcessingSkillEffect = false
  }
  
  async processSingleSkillEffect({ actorId, caster, effect: eff, defaultActionType }) {
    const skillName = eff.skillName || (eff.description ? eff.description.split('使用')[1]?.split(' ')[0] : '')
    const actionType = eff.actionType || defaultActionType || '攻击'
    
    // 阶段1：技能准备 - 显示技能名称
    if (skillName && this.onSkillAnimation) {
      this.onSkillAnimation(caster, { name: skillName })
    }
    
    // 短暂延迟让技能名称先显示
    await new Promise(resolve => setTimeout(resolve, 300))
    
    // 阶段2：技能释放 - 显示连线和箭头
    if (Array.isArray(eff.targetList) && this.onSkillTargets) {
      const targetIds = eff.targetList.map(t => t && t.targetId).filter(Boolean)
      if (targetIds.length) {
        this.onSkillTargets(actorId, targetIds, actionType, { skillType: actionType })
      }
    }
    
    // 等待连线动画和箭头到达目标
    const lineAnimationDuration = this.getLineAnimationDuration(actionType)
    await new Promise(resolve => setTimeout(resolve, lineAnimationDuration))
    
    // 阶段3：技能命中 - 同步执行所有效果
    await this.executeSkillImpact(eff)
    
    // 阶段4：效果展示完成
    const effectDisplayDuration = this.getEffectDisplayDuration(actionType)
    await new Promise(resolve => setTimeout(resolve, effectDisplayDuration))
  }
  
  // 获取连线动画持续时间：与 UI attackMs 保持一致，避免线已到达仍久等
  getLineAnimationDuration(actionType) {
    const ui = this.animationConfig.durations.ui
    const base = ui && typeof ui.attackMs === 'number' ? ui.attackMs : 2000
    const m = this.animationConfig.speedMultiplier || 1
    return Math.max(0, Math.floor(base * m))
  }

  // 获取效果展示持续时间（加快1倍）
  getEffectDisplayDuration(actionType) {
    const t = this.animationConfig.durations.effect[actionType] || this.animationConfig.durations.effect['默认']
    return Math.max(0, Math.floor(t * (this.animationConfig.speedMultiplier || 1)))
  }

  getIntervalForActionType(actionType) {
    const t = this.animationConfig.durations.interval[actionType] || this.animationConfig.durations.interval['默认']
    return Math.max(0, Math.floor(t * (this.animationConfig.speedMultiplier || 1)))
  }

  setSpeedMultiplier(mult) {
    const m = Number(mult)
    if (!isNaN(m) && m > 0) {
      this.animationConfig.speedMultiplier = m
    }
  }

  getUiDurations() {
    const ui = this.animationConfig.durations.ui
    const m = this.animationConfig.speedMultiplier || 1
    return {
      damageMs: Math.max(0, Math.floor(ui.damageMs * m)),
      attackMs: Math.max(0, Math.floor(ui.attackMs * m)),
      healMs: Math.max(0, Math.floor(ui.healMs * m)),
      buffMs: Math.max(0, Math.floor(ui.buffMs * m)),
      skillMs: Math.max(0, Math.floor(ui.skillMs * m)),
      hitSyncDelayMs: Math.max(0, ui.hitSyncDelayMs | 0)
    }
  }

  // 供页面读取：划线到达与清线之间的微延时（不随倍速变化）
  getHitSyncDelayMs() {
    const ui = this.animationConfig.durations.ui
    return Math.max(0, ui && ui.hitSyncDelayMs | 0)
  }
  
  // 执行技能命中效果
  async executeSkillImpact(eff) {
    // 处理抵抗效果
    if (eff.actionType === '控制' && Array.isArray(eff.targetList) && this.onResistHint) {
      for (const t of eff.targetList) {
        const resisted = !(t && t.isControl === true)
        if (!resisted) continue
        const targetUnit = this.findUnitByAnyKey(t.targetId)
        if (targetUnit) this.onResistHint(targetUnit, '被抵抗')
      }
    }
    
    // 记录战斗日志
    if (eff.description) {
      this.addLog(eff.description)
      if (this.onLog) this.onLog(eff.description)
    }
    
    // 处理所有目标效果
    if (Array.isArray(eff.targetList)) {
      // 分批处理目标，避免同时触发太多动画
      for (let i = 0; i < eff.targetList.length; i++) {
        const t = eff.targetList[i]
        const target = this.findUnitByAnyKey(t.targetId)
        
        if (target) {
          // 立即更新属性（血条变化）
          this.applyTargetUpdateAttr(target, t.updateAttr)
          
          // 触发视觉效果
          if (t.damage && t.damage > 0) {
            this.triggerDamageAnimation(target, t.damage, !!t.isCrit, this.findUnitByAnyKey(eff.actorId))
          }
          if (t.heal && t.heal > 0) {
            this.triggerHealAnimation(target, t.heal)
          }
          
          // 处理状态效果
          if (t.updateStatusEffect) {
            this.applyTargetStatusEffect(target, t.updateStatusEffect)
          }
          if (t.addStatusEffect) {
            this.appendTargetStatusEffect(target, t.addStatusEffect)
            if (this.onBuffPopup && target) {
              const list = Array.isArray(t.addStatusEffect) ? t.addStatusEffect : [t.addStatusEffect]
              list.forEach(name => {
                if (typeof name === 'string' && name.trim()) {
                  this.onBuffPopup(target, name)
                }
              })
            }
          }
        }
        
        // 多目标尽量无等待，保证数字与效果同步
        if (i < eff.targetList.length - 1) {
          await new Promise(resolve => setTimeout(resolve, 0))
        }
      }
    }
  }

  applyUpdateAttr(attrMap) {
    try {
      Object.keys(attrMap || {}).forEach(key => {
        const unit = this.findUnitByAnyKey(key)
        const changes = attrMap[key]
        if (!unit || !changes) return
        if (typeof changes.health === 'number') unit.hp = changes.health
        if (typeof changes.baseDamage === 'number') unit.baseDamage = changes.baseDamage
        if (typeof changes.defense === 'number') unit.defense = changes.defense
        if (typeof changes.speed === 'number') unit.speed = changes.speed
        if (typeof changes.hitRate === 'number') unit.hitRate = changes.hitRate
        if (typeof changes.dodgeRate === 'number') unit.dodgeRate = changes.dodgeRate
      })
    } catch (e) {}
  }

  // 针对目标的属性更新（targetList.updateAttr）
  applyTargetUpdateAttr(target, changes) {
    if (!target || !changes) return
    if (typeof changes.health === 'number') target.hp = changes.health
    if (typeof changes.baseDamage === 'number') target.baseDamage = changes.baseDamage
    if (typeof changes.defense === 'number') target.defense = changes.defense
    if (typeof changes.speed === 'number') target.speed = changes.speed
  }

  // 应用当前整局状态（round_start 等）
  applyCurStatusEffect(effectMap) {
    try {
      Object.keys(effectMap || {}).forEach(key => {
        const unit = this.findUnitByAnyKey(key)
        const list = effectMap[key]
        if (!unit) return
        unit.statusEffects = Array.isArray(list) ? list.slice() : []
      })
    } catch (e) {}
  }

  // 应用目标的状态变更（targetList.updateStatusEffect）
  applyTargetStatusEffect(target, effectList) {
    if (!target) return
    const list = Array.isArray(effectList) ? effectList : []
    // 新增：去重规则，支持字符串或对象{name}
    const normalize = (x) => typeof x === 'string' ? x : (x && x.name ? String(x.name) : '')
    const unique = []
    const seen = new Set()
    for (const e of list) {
      const k = normalize(e)
      if (k && !seen.has(k)) { seen.add(k); unique.push(k) }
    }
    target.statusEffects = unique
  }

  // 增量追加状态效果（targetList.addStatusEffect）
  appendTargetStatusEffect(target, addList) {
    if (!target) return
    const append = Array.isArray(addList) ? addList : (addList ? [addList] : [])
    const normalize = (x) => typeof x === 'string' ? x : (x && x.name ? String(x.name) : '')
    const existing = Array.isArray(target.statusEffects) ? target.statusEffects.map(normalize).filter(Boolean) : []
    const merged = existing.slice()
    for (const x of append) {
      const k = normalize(x)
      if (k && merged.indexOf(k) === -1) merged.push(k)
    }
    target.statusEffects = merged
    
    // 调试日志：确保状态效果正确应用到所有单位（包括敌方后排）
    console.log(`[Status Effect] Applied to ${target.name} (ID: ${target.id}, Position: ${target.position}):`, target.statusEffects)
  }

  // 通过 id 或 name+id 映射查找单位
  findUnitByAnyKey(key) {
    const all = [...this.playerUnits, ...this.enemyUnits]
    // 仅按唯一 id 查找，不再做 name+id 或前缀兼容
    const unit = all.find(u => String(u.id) === String(key))
    return unit || null
  }

  /**
   * 执行单位行动
   */
  async executeUnitAction(unit) {
    const targets = this.selectTargets(unit)
    if (targets.length === 0) return

    const skill = this.selectSkill(unit)
    const target = targets[Math.floor(Math.random() * targets.length)]

    await this.useSkill(unit, skill, target)
  }

  /**
   * 选择目标
   */
  selectTargets(unit) {
    if (unit.type === 'player') {
      return this.enemyUnits.filter(u => u.isAlive && u.id !== unit.id)
    } else {
      return this.playerUnits.filter(u => u.isAlive && u.id !== unit.id)
    }
  }

  /**
   * 选择技能
   */
  selectSkill(unit) {
    const availableSkills = unit.skills.filter(skill => 
      skill.rage_cost <= (unit.rage || 0)
    )
    
    if (availableSkills.length === 0) {
      // 返回基础攻击
      return {
        id: 'basic_attack',
        name: '基础攻击',
        type: 'attack',
        target_type: 'single',
        rage_cost: 0,
        effects: [{
          type: 'damage',
          base_damage: unit.baseDamage || unit.attack || 0,
          damage_ratio: 1.0
        }]
      }
    }

    return availableSkills[Math.floor(Math.random() * availableSkills.length)]
  }

  /**
   * 使用技能
   */
  async useSkill(caster, skill, target) {
    this.addLog(`${caster.name} 使用了 ${skill.name}`)
    if (this.onLog) this.onLog(`${caster.name} 使用了 ${skill.name}`)

    // UI层：在AI模式也触发技能名称提示
    if (this.onSkillAnimation && skill && skill.name) {
      this.onSkillAnimation(caster, { name: skill.name })
    }
    
    // 记录技能使用
    if (!this.battleState.skillsUsed.includes(skill.id)) {
      this.battleState.skillsUsed.push(skill.id)
    }

    // 处理技能效果
    for (const effect of skill.effects) {
      await this.applySkillEffect(caster, target, effect, skill)
    }

    // 消耗怒气
    if (caster.rage) {
      caster.rage = Math.max(0, caster.rage - skill.rage_cost)
    }
  }

  /**
   * 应用技能效果
   */
  async applySkillEffect(caster, target, effect, skill) {
    switch (effect.type) {
      case 'damage':
        await this.applyDamage(caster, target, effect)
        break
      case 'heal':
        await this.applyHeal(caster, target, effect)
        break
      case 'buff':
        await this.applyBuff(target, effect)
        break
      case 'debuff':
        await this.applyDebuff(target, effect)
        break
    }
  }

  /**
   * 应用伤害
   */
  applyDamage(attacker, target, effect) {
    // 防御性检查：避免自攻自
    if (attacker && target && attacker.id === target.id) {
      return
    }
    let damage = effect.base_damage || 0
    damage += (attacker.baseDamage || attacker.attack || 0) * (effect.damage_ratio || 1.0)
    
    // 应用伤害增加
    damage *= (1 + (attacker.damageIncrease || 0) / 100)
    
    // 计算防御减免
    const defense = target.defense || 0
    damage = Math.max(1, damage - defense)
    
    // 应用伤害减免
    damage *= (1 - (target.damageReduction || 0) / 100)
    
    // 暴击判断
    const critChance = (attacker.critRate || 0) / 100
    const isCrit = Math.random() < critChance
    if (isCrit) {
      damage *= 2
      this.battleState.criticalHits++
      this.addLog(`暴击！`)
    }
    
    // 随机浮动
    damage = Math.floor(damage * (0.9 + Math.random() * 0.2))
    
    // 应用伤害
    target.hp = Math.max(0, target.hp - damage)
    
    // 记录伤害统计
    if (attacker.type === 'player') {
      this.battleState.totalDamageDealt += damage
    } else {
      this.battleState.totalDamageTaken += damage
    }
    
    this.addLog(`${target.name} 受到了 ${damage} 点伤害`)
    
    // 检查目标是否死亡
    if (target.hp <= 0) {
      target.isAlive = false
      this.addLog(`${target.name} 被击败了！`)
    }

    // 触发UI更新（携带攻击者）
    this.triggerDamageAnimation(target, damage, isCrit, attacker)
  }

  /**
   * 应用治疗
   */
  applyHeal(caster, target, effect) {
    let healAmount = effect.base_heal || 0
    healAmount += (caster.baseDamage || caster.attack || 0) * (effect.heal_ratio || 0.5)
    
    const actualHeal = Math.min(healAmount, target.maxHp - target.hp)
    target.hp += actualHeal
    
    this.addLog(`${target.name} 恢复了 ${actualHeal} 点生命值`)
    this.triggerHealAnimation(target, actualHeal)
  }

  /**
   * 检查战斗是否结束
   */
  checkBattleEnd() {
    const alivePlayerUnits = this.playerUnits.filter(u => u.isAlive)
    const aliveEnemyUnits = this.enemyUnits.filter(u => u.isAlive)
    
    if (alivePlayerUnits.length === 0) {
      this.battleState.winner = 'enemy'
      this.addLog('战斗失败！')
      return true
    }
    
    if (aliveEnemyUnits.length === 0) {
      this.battleState.winner = 'player'
      this.addLog('战斗胜利！')
      return true
    }
    
    return false
  }

  /**
   * 更新状态效果 - 静默刷新，不播放动画
   */
  updateStatusEffects() {
    const allUnits = [...this.playerUnits, ...this.enemyUnits]
    
    allUnits.forEach(unit => {
      if (!Array.isArray(unit.statusEffects)) return
      
      // 静默移除已失效的状态效果，不播放动画或日志
      unit.statusEffects = unit.statusEffects.filter(effect => {
        // 如果状态效果是字符串格式，保留它（永久效果）
        if (typeof effect === 'string') return true
        
        // 如果状态效果有持续时间，检查是否过期
        if (effect && typeof effect === 'object' && typeof effect.duration === 'number') {
          effect.duration--
          return effect.duration > 0
        }
        
        // 其他格式的状态效果保留
        return true
      })
    })
  }

  /**
   * 提交战斗结果到后端
   */
  async submitBattleResult() {
    if (!this.battleState.isFinished) return false

    const battleDuration = Math.floor((Date.now() - this.battleState.battleStartTime) / 1000)
    const isVictory = this.battleState.winner === 'player'

    // 生成战斗数据哈希（简单的防作弊机制）
    const battleHash = this.generateBattleHash()

    try {
      const response = await request({
        url: '/combat/submit',
        method: 'POST',
        data: {
          battle_id: this.battleState.battleId,
          result: isVictory ? 'victory' : 'defeat',
          battle_duration: battleDuration,
          rounds_count: this.battleState.currentRound,
          total_damage_dealt: this.battleState.totalDamageDealt,
          total_damage_taken: this.battleState.totalDamageTaken,
          skills_used: this.battleState.skillsUsed,
          critical_hits: this.battleState.criticalHits,
          battle_hash: battleHash
        }
      })
      
      return response.data
    } catch (error) {
      console.error('提交战斗结果失败:', error)
      // 返回模拟结果
      return {
        success: true,
        rewards: {
          exp: isVictory ? 100 : 50,
          gold: isVictory ? 50 : 20,
          items: isVictory ? ['经验丹'] : []
        },
        message: isVictory ? '战斗胜利！获得丰厚奖励！' : '战斗失败，继续努力！'
      }
    }
  }

  /**
   * 生成战斗数据哈希
   */
  generateBattleHash() {
    const data = {
      battleId: this.battleState.battleId,
      rounds: this.battleState.currentRound,
      damageDealt: this.battleState.totalDamageDealt,
      damageTaken: this.battleState.totalDamageTaken,
      winner: this.battleState.winner
    }
    
    // 简单的哈希算法（实际项目中应使用更安全的方法）
    return btoa(JSON.stringify(data)).replace(/[^a-zA-Z0-9]/g, '').substring(0, 32)
  }

  /**
   * 添加战斗日志
   */
  addLog(message) {
    this.battleState.battleLog.push({
      round: this.battleState.currentRound,
      message: message,
      timestamp: Date.now()
    })
  }

  /**
   * 触发伤害动画（由UI层实现）
   */
  triggerDamageAnimation(target, damage, isCrit, attacker) {
    // 这个方法会被UI层重写以实现具体的动画效果
    if (this.onDamageAnimation) {
      this.onDamageAnimation(target, damage, isCrit, attacker)
    }
  }

  /**
   * 触发治疗动画（由UI层实现）
   */
  triggerHealAnimation(target, healAmount) {
    // 这个方法会被UI层重写以实现具体的动画效果
    if (this.onHealAnimation) {
      this.onHealAnimation(target, healAmount)
    }
  }

  /**
   * 获取当前战斗状态
   */
  getBattleState() {
    return {
      ...this.battleState,
      playerUnits: this.playerUnits,
      enemyUnits: this.enemyUnits,
      turnQueue: this.turnQueue
    }
  }

  /**
   * 重置战斗引擎
   */
  reset() {
    this.battleData = null
    this.battleState = {
      currentRound: 0,
      isFinished: false,
      winner: null,
      battleLog: [],
      totalDamageDealt: 0,
      totalDamageTaken: 0,
      skillsUsed: [],
      criticalHits: 0,
      battleStartTime: null,
      battleId: null
    }
    this.playerUnits = []
    this.enemyUnits = []
    this.turnQueue = []

    // 清理后端模式状态
    this.mode = 'ai'
    this.events = []
    this.eventIndex = 0
  }
}

export default BattleEngine